#include <iostream>
#include <unistd.h>
#include <pthread.h> //原生线程库
#include <string>
#include <vector>
// 多线程版本

// 任务类
class Task
{
public:
    Task()
    {
    }
    void setdata(int x, int y)
    {
        _data_x = x;
        _data_y = y;
    }
    int excute()
    {
        return _data_x + _data_y;
    }
    ~Task()
    {
    }

private:
    int _data_x;
    int _data_y;
};

// 传入线程函数的类，包含线程名称与要执行的数据
class Pthread_Data
{
public:
    Pthread_Data(int x, int y, std::string name)
        : _name(name)
    {
        _t.setdata(x, y); // 初始化Task
    }
    int run()
    {
        return _t.excute();
    }
    std::string name()
    {
        return _name;
    }
    ~Pthread_Data()
    {
    }

private:
    std::string _name;
    Task _t;
};

// 返回的结果类，包含线程名称与结果
class Result
{
public:
    Result()
    {
    }
    void SetResult(std::string name, int result)
    {
        _pthread_name = name;
        _result = result;
    }
    std::string name()
    {
        return _pthread_name;
    }
    int result()
    {
        return _result;
    }
    void Print()
    {
        std::cout << "pthread--name: " << _pthread_name << ", result:" << _result << std::endl;
    }
    ~Result()
    {
    }

private:
    std::string _pthread_name;
    int _result;
};

void *pthread_run(void *args)
{
    Pthread_Data *td = static_cast<Pthread_Data *>(args); // 显式强转
    std::cout << "start currently pthread :" << td->name() << std::endl;
    sleep(1);
    std::string name = td->name();
    int result = td->run();     // 执行任务
    delete td;                  // 每个线程自己回收td
    Result *res = new Result(); // 将返回结果与线程名放入Result
    res->SetResult(name, result);
    // std::cout << "finish currently pthread :" << td->name() << std::endl;
    return res; // 返回
}

int main(int argc, char *argv[])
{
    srand(time(nullptr));
    if (argc != 2)
    {
        std::cout << "please enter right parameter..." << std::endl;
        return -1;
    }
    int Pnumber = std::stoi(argv[1]); // 记录传入的需创建的线程数

    // 创建线程
    std::vector<pthread_t> tids;
    std::string name = "pthread-";
    for (int i = 1; i <= Pnumber; i++)
    {
        sleep(1);
        // std::string name_i=name+std::to_string(i);
        int x = rand() % 100, y = rand() % 100;
        Pthread_Data *td = new Pthread_Data(x, y, name + std::to_string(i));
        pthread_t tid;
        // 创建线程
        pthread_create(&tid, nullptr, pthread_run, td); // 传入的参数要注意
        tids.push_back(tid);
    }

    // 回收线程
    std::vector<Result *> results;
    void *ret = nullptr;
    for (auto tid : tids)
    {
        sleep(1);
        // 等待回收并返回结果
        pthread_join(tid, &ret);
        Result *res = (Result *)ret;
        results.push_back(res);
    }

    // 打印结果
    for (auto res : results)
    {
        res->Print();
        delete res;
    }
    return 0;
}

// // 改变传入的参数，当前为单线程版本

// // 任务类
// class Task
// {
// public:
//     Task()
//     {
//     }
//     void setdata(int x, int y)
//     {
//         _data_x = x;
//         _data_y = y;
//     }
//     int excute()
//     {
//         return _data_x + _data_y;
//     }
//     ~Task()
//     {
//     }

// private:
//     int _data_x;
//     int _data_y;
// };

// // 传入线程函数的类，包含线程名称与要执行的数据
// class Pthread_Data
// {
// public:
//     Pthread_Data(int x, int y, std::string name)
//         : _name(name)
//     {
//         _t.setdata(x, y); // 初始化Task
//     }
//     int run()
//     {
//         return _t.excute();
//     }
//     std::string name()
//     {
//         return _name;
//     }
//     ~Pthread_Data()
//     {
//     }

// private:
//     std::string _name;
//     Task _t;
// };

// // 返回的结果类，包含线程名称与结果
// class Result
// {
// public:
//     Result()
//     {
//     }
//     void SetResult(std::string name, int result)
//     {
//         _pthread_name = name;
//         _result = result;
//     }
//     std::string name()
//     {
//         return _pthread_name;
//     }
//     int result()
//     {
//         return _result;
//     }
//     void Print()
//     {
//         std::cout << "pthread--name: " << _pthread_name << ", result:" << _result << std::endl;
//     }
//     ~Result()
//     {
//     }

// private:
//     std::string _pthread_name;
//     int _result;
// };

// void *pthread_run(void *args)
// {
//     Pthread_Data *td = static_cast<Pthread_Data *>(args);//显式强转
//     std::string name=td->name();
//     int result = td->run();     // 执行任务
//     delete td;//每个线程自己回收td
//     Result *res = new Result(); // 将返回结果与线程名放入Result
//     res->SetResult(name, result);
//     return res; // 返回
// }

// int main()
// {
//     std::string name = "pthread-1";
//     Pthread_Data *td = new Pthread_Data(1, 2, name);
//     pthread_t tid;
//     // 创建线程
//     pthread_create(&tid, nullptr, pthread_run, td); // 传入的参数要注意
//     void *ret = nullptr;
//     // 等待回收并返回结果
//     pthread_join(tid, &ret);
//     Result *res = (Result *)ret;
//     res->Print();//打印结果
//     // 回收动态开辟的空间
//     delete res;

//     return 0;
// }

// 线程的创建与销毁完成

// void* pthread_run(void* args)
// {
//     int* a=(int*)args;
//     int cnt=5;
//     while(cnt--)
//     {
//         std::cout<<*a<<std::endl;
//     }
//     // int* ret=new int(123);
//     // return (void*)ret;
//     return (void*)123;
// }

// int main()
// {
//     pthread_t tid;
//     int a=10;
//     pthread_create(&tid,nullptr,pthread_run,&a);
//     void* ret=nullptr;
//     pthread_join(tid,&ret);//注意，这里是ret指向线程函数返回的值
//     //int* retval=(int*)ret;
//     //std::cout<<"wait success... ,ret:"<<*retval<<std::endl;//在这里对其进行解引用，如果不是动态开辟的会出错
//     std::cout<<"wait success... ,ret:"<<(long long)ret<<std::endl;//这里不需要线程函数返回动态开辟的空间，因为没有解引用，long long与指针都是8字节
//     //delete retval;
//     return 0;
// }